package com.spring.Service;

import com.spring.Entity.ContractEntity;
import com.spring.Entity.PaylogEntity;
import com.spring.Entity.UserEntity;
import com.spring.Repository.ContractRepository;
import com.spring.Repository.PaylogRepository;
import com.spring.Service.Interface.ContractService;
import com.spring.Service.Interface.PayLogService;
import com.spring.Service.Interface.UserServie;
import com.spring.Util.STATUS;
import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;
import jxl.read.biff.BiffException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.transaction.Transactional;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.Date;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * Created by Arabira on 2016/8/5.
 */
@Service("contractService")
@Transactional
public class ContractServiceImpl implements ContractService {
    @Autowired
    private ContractRepository contractRepository;
    @Autowired
    private UserServie userServie;
    @Autowired
    private PayLogService payLogService;
    @Autowired
    private PaylogRepository paylogRepository;
    private Map<String, Object> response;

    //如果添加的合同有预支付次数记录，自动添加相应栏位在相应表中
    private void preparyPaylog(int Times, String contractId) {
        for (int i = 0; i < Times; i++) {
            PaylogEntity paylogEntity = null;
            paylogEntity = new PaylogEntity();
            paylogEntity.setContractId(contractId);
            paylogEntity.setMoney("0");
            paylogEntity.setWarnOrNot(true);
            paylogRepository.saveAndFlush(paylogEntity);
        }
    }

    @Override
    public int addContract(ContractEntity contractEntity, String userId) {
        if (StringUtils.isBlank(contractEntity.getContractId())) {
            return STATUS.ID_EMPTY;
        }
        ContractEntity check = contractRepository.findOne(contractEntity.getContractId());
        if (null != check) {
            return STATUS.EXISTS;
        }
        //默认需要填写的有userID、statTime、Times、paidTime、warnOrNot
        contractEntity.setUserId(userId);
//        contractEntity.setStart(Date.valueOf(LocalDate.now()));
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        int random = new Random().nextInt(90) + 10;
        contractEntity.setId(sdf.format(new java.util.Date()) + random);
        if (null == contractEntity.getWarnOrNor()) {
            contractEntity.setWarnOrNor(false);
        }
        if (null == contractEntity.getPaidNum()) {
            contractEntity.setPaidNum(0);
        }
        contractRepository.saveAndFlush(contractEntity);
        if (contractEntity.getTimes() == null || contractEntity.getTimes() < 1) {
            contractEntity.setTimes(0);
        } else {
            preparyPaylog(contractEntity.getTimes(), contractEntity.getId());
        }
        return STATUS.SUCCESS;
    }

    @Override
    public String addByExcel(MultipartFile file) throws IOException, BiffException, ParseException {
        String message;
        File file1 = new File("ContractMSTemp");
        FileOutputStream fileOutputStream = new FileOutputStream(file1);
        BufferedOutputStream outputStream = new BufferedOutputStream(fileOutputStream);
        outputStream.write(file.getBytes());
        Workbook workbook = Workbook.getWorkbook(file1);
        Sheet sheet = workbook.getSheet(0);
        int rows = sheet.getRows();
        for (int i = 1; i < rows; i++) {
            Cell cell = null;
            ContractEntity contractEntity = new ContractEntity();
            //合同编号
            if ((cell = sheet.getCell(0, i)) != null && !StringUtils.isBlank(cell.getContents())) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
                int random = new Random().nextInt(90) + 10;
                contractEntity.setId(sdf.format(new java.util.Date()) + random);
                ContractEntity check = contractRepository.findByContractID(cell.getContents());
                if(check != null){
                    message = "Sheet1第" + (i+1) + "行：" + check.getContractId() + "编号合同已存在";
                    return message;
                }
                contractEntity.setContractId(cell.getContents());
            } else {
                message = "Sheet1第" + (i+1) + "行：合同编号不为空";
                return message;
            }
            //合同名称
            if ((cell = sheet.getCell(1, i)) != null && !StringUtils.isBlank(cell.getContents())) {
                contractEntity.setContractName(cell.getContents());
            } else {
                message = "Sheet1第" + (i+1) + "行：合同名称不为空";
                return message;
            }
            //提交人工号
            if ((cell = sheet.getCell(2, i)) != null && !StringUtils.isBlank(cell.getContents())) {
                String userId = cell.getContents();
                UserEntity userEntity = userServie.findByUserName(userId);

                contractEntity.setUserId(userEntity.getId());
            } else {
                message = "Sheet1第" + (i+1) + "行：提交人工号不为空";
                return message;
            }
            //起始时间
            if ((cell = sheet.getCell(3, i)) != null && !StringUtils.isBlank(cell.getContents())) {
                String str = cell.getContents();
                SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
                java.util.Date tempDate = format.parse(str);
                java.sql.Date date = new java.sql.Date(tempDate.getTime());
                contractEntity.setStart(date);
            } else {
                message = "Sheet1第" + (i+1) + "行合同起始时间不为空";
                return message;
            }
            //截止时间
            if ((cell = sheet.getCell(4, i)) != null && !StringUtils.isBlank(cell.getContents())) {
                String str = cell.getContents();
                SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
                java.util.Date tempDate = format.parse(str);
                java.sql.Date date = new java.sql.Date(tempDate.getTime());
                contractEntity.setDeadline(date);
            } else {
                message = "Sheet1第" + (i+1) + "行：合同截止时间不为空";
                return message;
            }
            //是否提醒
            if ((cell = sheet.getCell(5, i)) != null && !StringUtils.isBlank(cell.getContents())) {
                String str = cell.getContents();
                String flag = str;
                if (flag == "是") {
                        contractEntity.setWarnOrNor(true);
                    cell = sheet.getCell(6, i);

                    str = cell.getContents();
                    SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
                    java.util.Date tempDate = format.parse(str);
                    java.sql.Date date = new java.sql.Date(tempDate.getTime());

                    contractEntity.setRemind(date);
                } else {
                    contractEntity.setWarnOrNor(false);
                }
            } else {
                message = "Sheet1第" + (i+1) + "行：合同是否提醒不为空";
                return message;
            }
            //付款期数
            if ((cell = sheet.getCell(7, i)) != null && !StringUtils.isBlank(cell.getContents())) {
                contractEntity.setTimes(Integer.valueOf(cell.getContents()));
            } else {
                message = "Sheet1第" + (i+1) + "行：提交人工号不为空";
                return message;
            }
            contractRepository.saveAndFlush(contractEntity);
        }
       message =  payLogService.addByExcel(file);
        return message;
    }

    @Override
    public int updateContract(String contractId, String contractName, Date startTime, Date deadline, Date remindTime, Integer times,Boolean warn) {
        int status = STATUS.FAIL;
        ContractEntity contractEntity = contractRepository.findOne(contractId);
        if (StringUtils.isBlank(contractEntity.getContractId())) {
            status = STATUS.ID_EMPTY;
        } else {
            if (!StringUtils.isBlank(contractName)) {
                contractEntity.setContractName(contractName);
                status = STATUS.SUCCESS;
            }
            if (null != times) {
                if (times > 0) {
                    contractEntity.setTimes(times);
                    status = STATUS.SUCCESS;
                } else {
                    status = STATUS.MINUS;
                }
            }
            if (null != startTime) {
                if (null == contractEntity.getDeadline()) {
                    if (null == contractEntity.getRemind()) {
                        contractEntity.setStart(startTime);
                        status = STATUS.SUCCESS;
                    } else if (startTime.compareTo(contractEntity.getRemind()) < 0) {
                        contractEntity.setStart(startTime);
                        status = STATUS.SUCCESS;
                    } else {
                        status = STATUS.STARTTIMEERROR;
                    }
                } else if (startTime.compareTo(contractEntity.getDeadline()) < 0) {
                    contractEntity.setStart(startTime);
                    status = STATUS.SUCCESS;
                } else {
                    status = STATUS.STARTTIMEERROR;
                }
            }
            if (null != deadline) {
                if (deadline.compareTo(contractEntity.getStart()) > 0) {
                    contractEntity.setDeadline(deadline);
                    status = STATUS.SUCCESS;
                } else {
                    status = STATUS.DEADLINEERROR;
                }
            }
            if(warn) {
                contractEntity.setWarnOrNor(warn);
                if (null != remindTime) {
                    if (null == contractEntity.getDeadline()) {
                        if (contractEntity.getStart().compareTo(remindTime) < 0) {
                            contractEntity.setRemind(remindTime);
                            status = STATUS.SUCCESS;
                        } else {
                            status = STATUS.REMINDTIMEERROR;
                        }
                    } else if (contractEntity.getStart().compareTo(remindTime) < 0
                            &&
                            contractEntity.getDeadline().compareTo(remindTime) > 0) {
                        contractEntity.setRemind(remindTime);
                        status = STATUS.SUCCESS;
                    } else {
                        status = STATUS.REMINDTIMEERROR;
                    }
                }
            }else{
                contractEntity.setWarnOrNor(warn);
                contractEntity.setRemind(null);
            }

            if (status == STATUS.SUCCESS) {
                contractRepository.saveAndFlush(contractEntity);
            }
        }
        return status;
    }

    @Override
    public Map<String, Object> onOrOff(String contractId) {
        response = new HashMap<>();
        if (StringUtils.isBlank(contractId)) {
            response.put("status", "error");
            response.put("description", "合同号不可为空");
            return response;
        }
        ContractEntity contractEntity = contractRepository.findOne(contractId);
        if (null == contractEntity) {
            response.put("status", "error");
            response.put("descrition", "合同不存在");
            return response;
        } else {
            if (contractEntity.getWarnOrNor()) {
                contractEntity.setWarnOrNor(false);
            } else {
                contractEntity.setWarnOrNor(true);
            }
            contractRepository.saveAndFlush(contractEntity);
            response.put("status", "ok");
            response.put("description", "修改成功");
            response.put("body", contractEntity.getWarnOrNor());
            return response;
        }
    }

    //通过用户ID查找所有此用户的合同信息
    @Override
    public Map<String, Object> findContractByUserId(String userId, Integer pageNum, Integer pageSize) {
        response = new HashMap<>();
        if (pageNum == null || pageSize == null) {
            response.put("status", "error");
            response.put("description", "未登录或页数为空");
            return response;
        }
        if (pageNum < 0) {
            pageNum = 0;
        }
        if (pageSize < 0) {
            pageSize = 10;
        }
//        Page page = contractRepository.findByUserIdPageable(userId, new PageRequest(pageNum, pageSize));
        List page = contractRepository.findAllByUserId(userId);
        response.put("status", "ok");
        response.put("body", page);
//        response.put("pageNum", pageNum);
//        response.put("totalPage", page.getTotalPages());
        return response;
    }

    @Override
    public ContractEntity findContractById(String contractId) {
        ContractEntity contractEntity = contractRepository.findOne(contractId);
        return contractEntity;
    }

    //自动发送邮件使用，通过当前时间查找需要提醒的合同信息
    @Override
    public ContractEntity[] findContractByRemindTime() {
        ContractEntity[] remind = contractRepository.findByRemindTimeAndWarnOrNot(LocalDate.now());
        return remind;
    }


    @Override
    public Map<String, Object> findContractAll() {
        response = new HashMap<>();
//        if (pageNum == null || pageSize == null) {
//            response.put("status", "error");
//            response.put("description", "未登录或页数为空");
//            return response;
//        }
//        if (pageNum < 0) {
//            pageNum = 0;
//        }
//        if (pageSize < 0) {
//            pageSize = 10;
//        }
//        Page page = contractRepository.findAllPageable(new PageRequest(pageNum, pageSize));
//        Page page = contractRepository.findAllPageable(new PageRequest(pageNum, pageSize));
        List page = contractRepository.findAllPageable();
        response.put("status", "ok");
        response.put("body", page);
//        response.put("pageNum", pageNum);
//        response.put("totalPage", page.getTotalPages());
        return response;
    }

    @Override
    public Map<String, Object> findReqContractByAdmin(String contractId, String contractName, String userName, String startS, String startE, String deadlineS, String deadlineE) {
        response = new HashMap();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        contractId = ((contractId != null) ? "%" + contractId + "%" : "");
        contractName = ((contractName != null) ? "%" + contractName + "%" : "");
        userName = ((userName != null) ? "%" + userName + "%" : "");

        Date startST = null;
        Date startET = null;
        Date deadlineST = null;
        Date deadlineET = null;
        try {
            startST = new java.sql.Date(sdf.parse(startS).getTime());
            startET = new java.sql.Date(sdf.parse(startE).getTime());
            deadlineST = new java.sql.Date(sdf.parse(deadlineS).getTime());
            deadlineET = new java.sql.Date(sdf.parse(deadlineE).getTime());
        } catch (ParseException e) {
            e.printStackTrace();
        }


        List page = contractRepository.findReqByAdmin(contractId, contractName, userName, startST, startET, deadlineST, deadlineET);

        if (page.size() == 0) {
            response.put("status", "datanull");
        } else {
            response.put("status", "ok");
            response.put("body", page);
        }
        return response;
    }

    @Override
    public int deleteContract(String contractId) {
//        int status = STATUS.FAIL;
        PaylogEntity[] paylogs = paylogRepository.findByContractId(contractId);
        for (int i = 0; i < paylogs.length; i++){
            paylogRepository.delete(paylogs[i]);

        }
        contractRepository.delete(contractId);
        return STATUS.SUCCESS;
    }
}
